/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.prabhu.jeazyprops.props;

import com.prabhu.jeazyprops.bean.KeyValue;
import com.prabhu.jeazyprops.interfaces.PropsEncrypt;
import com.prabhu.cmdwindow.ui.Display;
import com.prabhu.jeazyprops.validation.Validator;
import java.awt.Button;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.border.EtchedBorder;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * This is the Base Class for the Property Bean Class
 * @author Pinky
 */
public abstract class BaseProps
        extends Display
{

    protected Properties lProperties;
    protected File lPropsFile;
    protected PropsEncrypt lPropsEncrypt;
    private String lPropsFilePath;
    protected String lSufixProps = "";
    protected String lPrefixProps = "";
    private boolean isAbleToSave = false;
    private PropsFiletype lPropsFiletype;

    public enum PropsFiletype
    {

        XML, PROPERTIES
    };

    /**
     * Sets the Encryption algorithm for the properties
     * @param pPropsEncrypt
     */
    public void setEncryption( PropsEncrypt pPropsEncrypt )
    {
        lPropsEncrypt = pPropsEncrypt;
    }

    /**
     * Loads the Properties from File to Bean
     * @param PropsFilePath Relative or Absolute path of the Properties File
     */
    public void loadProperties( String PropsFilePath )
    {
        lPropsFilePath = PropsFilePath;
        if ( lPropsFilePath.endsWith( ".xml" ) )
        {
            lPropsFiletype = PropsFiletype.XML;
        }
        else if ( lPropsFilePath.endsWith( ".properties" ) )
        {
            lPropsFiletype = PropsFiletype.PROPERTIES;
        }

        FileInputStream pFileInputStream = null;

        lPropsFile = new File( PropsFilePath );
        try
        {
            if ( lPropsFile.exists() )
            {
                pFileInputStream = new FileInputStream( lPropsFile );
            }
            else
            {
                if ( lPropsFiletype == PropsFiletype.XML )
                {
                    createNewXMLFile();
                }
                else if ( lPropsFiletype == PropsFiletype.PROPERTIES )
                {
                    lPropsFile.createNewFile();
                }
                pFileInputStream = new FileInputStream( lPropsFile );
            }
            isAbleToSave = true;
            loadProperties( pFileInputStream, lPropsFiletype );
        }
        catch ( FileNotFoundException ex )
        {
            JOptionPane.showMessageDialog( null, "Properties File Not Found",
                                           "Alert", JOptionPane.ERROR_MESSAGE );
        }
        catch ( IOException ex )
        {
            JOptionPane.showMessageDialog( null,
                                           "Cannot able to Create Properties File",
                                           "Alert", JOptionPane.ERROR_MESSAGE );
        }
        finally
        {
            try
            {
                if ( pFileInputStream != null )
                {
                    pFileInputStream.close();
                }
            }
            catch ( IOException ex )
            {
                JOptionPane.showMessageDialog( null,
                                               "Cannot able to Close Properties File",
                                               "Alert",
                                               JOptionPane.ERROR_MESSAGE );
            }
        }
    }

    /**
     * Loads the Properties from input stream to Bean
     * @param pFileInputStream input stream of a file stream
     */
    public void loadProperties( InputStream pFileInputStream,
                                PropsFiletype pPropsFiletype )
    {
        lPropsFiletype = pPropsFiletype;
        lProperties = new Properties();
        try
        {
            if ( lPropsFiletype == PropsFiletype.XML )
            {
                lProperties.loadFromXML( pFileInputStream );
            }
            else if ( lPropsFiletype == PropsFiletype.PROPERTIES )
            {
                lProperties.load( pFileInputStream );
            }
            readProperties();
        }
        catch ( IOException ex )
        {
            JOptionPane.showMessageDialog( null,
                                           "Cannot able to Read Properties File (Format Error)",
                                           "Alert", JOptionPane.ERROR_MESSAGE );
        }
        finally
        {
            try
            {
                if ( pFileInputStream != null )
                {
                    pFileInputStream.close();
                }
            }
            catch ( IOException ex )
            {
                JOptionPane.showMessageDialog( null,
                                               "Cannot able to Close Properties File",
                                               "Alert",
                                               JOptionPane.ERROR_MESSAGE );
            }
        }
    }

    /**
     * Gets the integer property
     * @param Key Property Name (key value)
     * @param isEncrypt Whether the value is encrypted
     * @return The integer Property
     */
    private int getIntegerProperty( String Key, boolean isEncrypt )
    {
        try
        {
            if ( isEncrypt )
            {
                if ( lProperties.getProperty( Key, "0" ).equals( "0" ) )
                {
                    return Integer.valueOf( lProperties.getProperty( Key, "0" ) );
                }
                else
                {
                    if ( lPropsEncrypt == null )
                    {
                        JOptionPane.showMessageDialog( null,
                                                       "No Encryption Initalised",
                                                       "Alert",
                                                       JOptionPane.WARNING_MESSAGE );
                    }
                    return Integer.valueOf( lPropsEncrypt.decrypt( lProperties.
                            getProperty( Key ) ) );
                }
            }
            else
            {
                return Integer.valueOf( lProperties.getProperty( Key, "0" ) );
            }
        }
        catch ( NumberFormatException ex )
        {
            return 0;
        }
    }

    /**
     * Gets the double property
     * @param Key Property Name (key value)
     * @param isEncrypt Whether the value is encrypted
     * @return The double Property
     */
    private double getDoubleProperty( String Key, boolean isEncrypt )
    {
        try
        {
            if ( isEncrypt )
            {
                if ( lProperties.getProperty( Key, "0.0" ).equals( "0.0" ) )
                {
                    return Double.valueOf( lProperties.getProperty( Key, "0.0" ) );
                }
                else
                {
                    if ( lPropsEncrypt == null )
                    {
                        JOptionPane.showMessageDialog( null,
                                                       "No Encryption Initalised",
                                                       "Alert",
                                                       JOptionPane.WARNING_MESSAGE );
                    }
                    return Double.valueOf( lPropsEncrypt.decrypt( lProperties.
                            getProperty( Key ) ) );
                }
            }
            else
            {
                return Double.valueOf( lProperties.getProperty( Key, "0.0" ) );
            }
        }
        catch ( NumberFormatException ex )
        {
            return 0.0;
        }
    }

    /**
     * Gets the float property
     * @param Key Property Name (key value)
     * @param isEncrypt Whether the value is encrypted
     * @return The double Property
     */
    private float getFloatProperty( String Key, boolean isEncrypt )
    {
        try
        {
            if ( isEncrypt )
            {
                if ( lProperties.getProperty( Key, "0.0" ).equals( "0.0" ) )
                {
                    return Float.valueOf( lProperties.getProperty( Key, "0.0" ) );
                }
                else
                {
                    if ( lPropsEncrypt == null )
                    {
                        JOptionPane.showMessageDialog( null,
                                                       "No Encryption Initalised",
                                                       "Alert",
                                                       JOptionPane.WARNING_MESSAGE );
                    }
                    return Float.valueOf( lPropsEncrypt.decrypt( lProperties.
                            getProperty( Key ) ) );
                }
            }
            else
            {
                return Float.valueOf( lProperties.getProperty( Key, "0.0" ) );
            }
        }
        catch ( NumberFormatException ex )
        {
            return 0;
        }
    }

    /**
     * Gets the String property
     * @param Key Property Name (key value)
     * @param isEncrypt Whether the value is encrypted
     * @return The String Property
     */
    private String getStringProperty( String Key, boolean isEncrypt )
    {
        if ( isEncrypt )
        {
            if ( lProperties.getProperty( Key, "" ).equals( "" ) )
            {
                return lProperties.getProperty( Key, "" );
            }
            else
            {
                if ( lPropsEncrypt == null )
                {
                    JOptionPane.showMessageDialog( null,
                                                   "No Encryption Initalised",
                                                   "Alert",
                                                   JOptionPane.WARNING_MESSAGE );
                }
                return lPropsEncrypt.decrypt( lProperties.getProperty( Key ) );
            }
        }
        else
        {
            return lProperties.getProperty( Key, "" );
        }
    }

    /**
     * Gets the Boolean property
     * @param Key Property Name (key value)
     * @param isEncrypt Whether the value is encrypted
     * @return The Boolean Property
     */
    private boolean getBooleanProperty( String Key, boolean isEncrypt )
    {
        try
        {
            if ( isEncrypt )
            {
                if ( lPropsEncrypt == null )
                {
                    JOptionPane.showMessageDialog( null,
                                                   "No Encryption Initalised",
                                                   "Alert",
                                                   JOptionPane.WARNING_MESSAGE );
                }
                return Boolean.valueOf( lPropsEncrypt.decrypt( lProperties.
                        getProperty( Key ) ) );
            }
            else
            {
                return Boolean.valueOf( lProperties.getProperty( Key, "false" ) );
            }
        }
        catch ( NumberFormatException ex )
        {
            return false;
        }
    }

    /**
     * Sets the integer property
     * @param Key Property Name (key value)
     * @param Value Property Value (key value)
     * @return The integer Property
     */
    private void putStringProperty( String Key, String Value )
    {
        putStringProperty( Key, Value, false );
    }

    /**
     * Sets the String property
     * @param Key Property Name (key value)
     * @param Value Property Value (key value)
     * @param isEncrypt Whether the value is encrypted
     * @return The integer Property
     */
    private void putStringProperty( String Key, String Value, boolean isEncrypt )
    {
        if ( isEncrypt )
        {
            lProperties.put( Key, lPropsEncrypt.encrypt( Value ) );
        }
        else
        {
            lProperties.put( Key, Value );
        }
    }

    /**
     * Updates or saves the properties to the file
     * @return
     */
    private boolean updateProperties()
    {
        String pClassName = this.getClass().getName();
        try
        {
            Class<?> forName = Class.forName( pClassName );
            Object cast = forName.cast( this );
            Method[] methods = forName.getMethods();
            for ( int i = 0; i < methods.length; i++ )
            {
                Method method = methods[i];
                if ( method.getDeclaringClass().getName().equals( pClassName )
                        && method.getName().startsWith( "get" ) )
                {
                    String invoke = String.valueOf( method.invoke( cast ) );
                    Field field = null;
                    try
                    {
                        field = forName.getField( lPrefixProps + method.getName().
                                substring( 3 ) + lSufixProps );
                    }
                    catch ( NoSuchFieldException ex )
                    {
                        continue;
                    }
                    if ( field == null )
                    {
                        continue;
                    }
                    KeyValue currentValue = (KeyValue) field.get( cast );
                    putStringProperty( currentValue.key, invoke,
                                       currentValue.isEncrypted );
                }
            }
            if ( lPropsFilePath.endsWith( ".xml" ) )
            {
                lProperties.storeToXML( new FileOutputStream( lPropsFilePath ),
                                        null );
            }
            else if ( lPropsFilePath.endsWith( ".properties" ) )
            {
                lProperties.store( new FileOutputStream( lPropsFilePath ), null );
            }
            return true;
        }
        catch ( Exception ex )
        {
        }
        return false;
    }

    /**
     * Prints the Properties
     */
    public void printProperties()
    {
        String pClassName = this.getClass().getName();
        try
        {
            Class<?> forName = Class.forName( pClassName );
            Object cast = forName.cast( this );
            Method[] methods = forName.getMethods();
            printHeader();
            printColumn( "Properties List" );
            printHeader();
            for ( int i = 0; i < methods.length; i++ )
            {
                Method method = methods[i];
                if ( method.getDeclaringClass().getName().equals( pClassName )
                        && method.getName().startsWith( "get" ) )
                {
                    Field field = null;
                    try
                    {
                        field = forName.getField( lPrefixProps + method.getName().
                                substring( 3 ) + lSufixProps );
                    }
                    catch ( NoSuchFieldException ex )
                    {
                        continue;
                    }
                    if ( field == null )
                    {
                        continue;
                    }
                    String invoke = String.valueOf( method.invoke( cast ) );
                    printColumn( method.getName().substring( 3 ), invoke );
                }
            }
            printHeader();
            printColumn( "Powered By Prabhu.P (p.r.c.prabhu@gmail.com)" );
            printHeader();
        }
        catch ( Exception ex )
        {
        }
    }

    /**
     * Displays the Properties in a GUI for Editing and Updating
     */
    public void DisplaySettings()
    {
        JDialog lJDialog = null;
        lJDialog = new JDialog( lJDialog, "Properties Configuration" )
        {

            @Override
            public void setLayout( LayoutManager manager )
            {
                super.setLayout( manager );
                try
                {
                    for ( javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.
                            getInstalledLookAndFeels() )
                    {
                        if ( "Windows".equals( info.getName() ) )
                        {
                            javax.swing.UIManager.setLookAndFeel( info.
                                    getClassName() );
                            break;
                        }
                    }
                }
                catch ( ClassNotFoundException ex )
                {
                }
                catch ( InstantiationException ex )
                {
                }
                catch ( IllegalAccessException ex )
                {
                }
                catch ( javax.swing.UnsupportedLookAndFeelException ex )
                {
                }
            }
        };
        lJDialog.setDefaultCloseOperation(
                javax.swing.WindowConstants.DISPOSE_ON_CLOSE );
//        lJDialog.setAlwaysOnTop(true);
//        lJDialog.setTransferHandler(new TransferHandler(""));
        Validator lValidator = new Validator( this );
        JPanel lPanel = new JPanel();

        String pClassName = this.getClass().getName();
        int compscount = 0;
        try
        {
            Class<?> forName = Class.forName( pClassName );
            Object cast = forName.cast( this );
            Method[] methods = forName.getMethods();
            lPanel.setLayout( new GridBagLayout() );
            GridBagConstraints lBagConstraints = new GridBagConstraints();
            lBagConstraints.fill = GridBagConstraints.HORIZONTAL;
            lBagConstraints.weightx = 1.0;

            for ( int i = 0; i < methods.length; i++ )
            {
                Method method = methods[i];
                if ( method.getDeclaringClass().getName().equals( pClassName )
                        && method.getName().startsWith( "get" ) )
                {// && !method.getName().startsWith("getInstance")) {
                    String invoke = String.valueOf( method.invoke( cast ) );
                    Field field = null;
                    try
                    {
                        field = forName.getField( lPrefixProps + method.getName().
                                substring( 3 ) + lSufixProps );
                    }
                    catch ( NoSuchFieldException ex )
                    {
                        continue;
                    }
                    if ( field == null )
                    {
                        continue;
                    }
                    KeyValue currentKey = (KeyValue) field.get( cast );
                    lBagConstraints.fill = GridBagConstraints.CENTER;
                    lBagConstraints.gridx = 0;
                    lBagConstraints.gridy = compscount;
                    lBagConstraints.insets = new Insets( 5, 10, 5, 5 );
                    lBagConstraints.anchor = GridBagConstraints.EAST;
                    lBagConstraints.weightx = 0;

                    if ( currentKey.displayName != null )
                    {
                        lPanel.add( new JLabel( currentKey.displayName + " : " ),
                                    lBagConstraints );
                        lBagConstraints.fill = GridBagConstraints.HORIZONTAL;
                        lBagConstraints.gridx = 1;
                        lBagConstraints.gridy = compscount;
                        lBagConstraints.insets = new Insets( 5, 5, 5, 10 );
                        lBagConstraints.weightx = 1.0;
                        if ( method.getReturnType().getName().equals(
                                "java.lang.String" )
                                || method.getReturnType().getName().equals(
                                "int" ) || method.getReturnType().getName().
                                equals( "java.lang.Integer" )
                                || method.getReturnType().getName().equals(
                                "double" ) || method.getReturnType().getName().
                                equals( "java.lang.Double" )
                                || method.getReturnType().getName().equals(
                                "float" ) || method.getReturnType().getName().
                                equals( "java.lang.Float" ) )
                        {
                            if ( currentKey.isEncrypted )
                            {
                                currentKey.lComponent = new JPasswordField(
                                        invoke );
                                currentKey.lComponent.getAccessibleContext().
                                        setAccessibleName( lPrefixProps + method.
                                        getName().substring( 3 ) + lSufixProps );
                                currentKey.lComponent.setInputVerifier(
                                        lValidator );
                            }
                            else
                            {
                                currentKey.lComponent = new JTextField( invoke );
                                currentKey.lComponent.getAccessibleContext().
                                        setAccessibleName( lPrefixProps + method.
                                        getName().substring( 3 ) + lSufixProps );
                                currentKey.lComponent.setInputVerifier(
                                        lValidator );
                            }
                        }
                        else if ( method.getReturnType().getName().equals(
                                "java.lang.Boolean" ) || method.getReturnType().
                                getName().equals( "boolean" ) )
                        {
                            currentKey.lComponent = new JCheckBox();
                            currentKey.lComponent.getAccessibleContext().
                                    setAccessibleName( lPrefixProps + method.
                                    getName().substring( 3 ) + lSufixProps );
                            ((JCheckBox) currentKey.lComponent).setSelected( Boolean.
                                    valueOf( invoke ) );
                        }
                        lPanel.add( currentKey.lComponent, lBagConstraints );
                        compscount++;
                    }
                }
            }
            if ( isAbleToSave )
            {
                lBagConstraints.gridx = 0;
                lBagConstraints.gridwidth = 2;
                lBagConstraints.gridy = compscount;
                Button button = new Button( "Save" );
                button.addActionListener( new ActionListener()
                {

                    @Override
                    public void actionPerformed( ActionEvent e )
                    {
                        if ( ValidateData() && isAbleToSave )
                        {
                            packData();
                            if ( updateProperties() )
                            {
                                JOptionPane.showMessageDialog( null,
                                                               "Property file " + lPropsFilePath + " Updated Successfully",
                                                               "Update Success",
                                                               JOptionPane.INFORMATION_MESSAGE );
                            }
                            else
                            {
                                JOptionPane.showMessageDialog( null,
                                                               "Property file " + lPropsFilePath + " Update Failed",
                                                               "Error",
                                                               JOptionPane.ERROR_MESSAGE );
                            }
                        }
                        else
                        {
                            JOptionPane.showMessageDialog( null,
                                                           "Not able to update, Validation error.",
                                                           "Alert",
                                                           JOptionPane.WARNING_MESSAGE );
                        }
                    }
                } );
                lPanel.add( button, lBagConstraints );
                compscount++;
            }
            EtchedBorder etchedBorder = new EtchedBorder( EtchedBorder.LOWERED );
            etchedBorder.getBorderInsets( lPanel );
            lPanel.setBorder( etchedBorder );
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = gbc.gridy = 0;
            gbc.gridwidth = gbc.gridheight = 1;
            gbc.fill = GridBagConstraints.BOTH;
            gbc.anchor = GridBagConstraints.NORTHWEST;
            gbc.weightx = gbc.weighty = 100;
            gbc.insets = new Insets( 10, 10, 10, 10 );
            lJDialog.setLayout( new GridBagLayout() );
            lJDialog.add( lPanel, gbc );
            lJDialog.setBounds( new Rectangle( (520), (compscount * 35) + 40 ) );
            setWindowParameters( lJDialog );
            lJDialog.setVisible( true );
            lJDialog.setResizable( false );
        }
        catch ( Exception ex )
        {
        }
    }

    /**
     * Validates the text fields
     * @return true if all validation matches
     */
    private boolean ValidateData()
    {
        String pClassName = this.getClass().getName();
        boolean lReturn = true;
        try
        {
            Class<?> forName = Class.forName( pClassName );
            Object cast = forName.cast( this );
            Method[] methods = forName.getMethods();
            for ( int i = 0; i < methods.length; i++ )
            {
                Method method = methods[i];
                if ( method.getDeclaringClass().getName().equals( pClassName )
                        && method.getName().startsWith( "set" ) )
                {
                    Field field = null;
                    try
                    {
                        field = forName.getField( lPrefixProps + method.getName().
                                substring( 3 ) + lSufixProps );
                    }
                    catch ( NoSuchFieldException ex )
                    {
                        continue;
                    }
                    if ( field == null )
                    {
                        continue;
                    }
                    KeyValue currentKey = (KeyValue) field.get( cast );
                    if ( currentKey.displayName != null )
                    {
                        Class<?>[] parameterTypes = method.getParameterTypes();
                        if ( parameterTypes[0].getName().equals(
                                "java.lang.String" )
                                || parameterTypes[0].getName().equals( "int" ) || parameterTypes[0].
                                getName().equals( "java.lang.Integer" )
                                || parameterTypes[0].getName().equals( "double" ) || parameterTypes[0].
                                getName().equals( "java.lang.Double" )
                                || parameterTypes[0].getName().equals( "float" ) || parameterTypes[0].
                                getName().equals( "java.lang.Float" ) )
                        {
                            if ( currentKey.isEncrypted )
                            {
                                lReturn = lReturn && ((JPasswordField) currentKey.lComponent).
                                        getInputVerifier().verify(
                                        currentKey.lComponent );
                            }
                            else
                            {
                                lReturn = lReturn && ((JTextField) currentKey.lComponent).
                                        getInputVerifier().verify(
                                        currentKey.lComponent );
                            }
                        }
                    }
                }
            }
        }
        catch ( Exception ex )
        {
            lReturn = false;
        }
        return lReturn;
    }

    /**
     * Packs the Data from Bean fro Updating
     */
    private void packData()
    {
        String pClassName = this.getClass().getName();
        try
        {
            Class<?> forName = Class.forName( pClassName );
            Object cast = forName.cast( this );
            Method[] methods = forName.getMethods();
            for ( int i = 0; i < methods.length; i++ )
            {
                Method method = methods[i];
                if ( method.getDeclaringClass().getName().equals( pClassName )
                        && method.getName().startsWith( "set" ) )
                {
                    Field field = null;
                    try
                    {
                        field = forName.getField( lPrefixProps + method.getName().
                                substring( 3 ) + lSufixProps );
                    }
                    catch ( NoSuchFieldException ex )
                    {
                        continue;
                    }
                    if ( field == null )
                    {
                        continue;
                    }
                    KeyValue currentKey = (KeyValue) field.get( cast );
                    if ( currentKey.displayName != null )
                    {
                        Class<?>[] parameterTypes = method.getParameterTypes();
                        if ( parameterTypes[0].getName().equals(
                                "java.lang.String" ) )
                        {
                            if ( currentKey.isEncrypted )
                            {
                                String Property = String.valueOf( ((JPasswordField) currentKey.lComponent).
                                        getPassword() );
                                method.invoke( cast, Property );
                            }
                            else
                            {
                                String Property = ((JTextField) currentKey.lComponent).
                                        getText();
                                method.invoke( cast, Property );
                            }
                        }
                        else if ( parameterTypes[0].getName().equals( "int" ) || parameterTypes[0].
                                getName().equals( "java.lang.Integer" ) )
                        {
                            if ( currentKey.isEncrypted )
                            {
                                Integer Property = Integer.valueOf( String.
                                        valueOf( ((JPasswordField) currentKey.lComponent).
                                        getPassword() ) );
                                method.invoke( cast, Property );
                            }
                            else
                            {
                                Integer Property = Integer.valueOf( ((JTextField) currentKey.lComponent).
                                        getText() );
                                method.invoke( cast, Property );
                            }
                        }
                        else if ( parameterTypes[0].getName().equals( "double" ) || parameterTypes[0].
                                getName().equals( "java.lang.Double" ) )
                        {
                            if ( currentKey.isEncrypted )
                            {
                                Integer Property = Integer.valueOf( String.
                                        valueOf( ((JPasswordField) currentKey.lComponent).
                                        getPassword() ) );
                                method.invoke( cast, Property );
                            }
                            else
                            {
                                Double Property = Double.valueOf( ((JTextField) currentKey.lComponent).
                                        getText() );
                                method.invoke( cast, Property );
                            }
                        }
                        else if ( parameterTypes[0].getName().equals( "float" ) || parameterTypes[0].
                                getName().equals( "java.lang.Float" ) )
                        {
                            if ( currentKey.isEncrypted )
                            {
                                Float Property = Float.valueOf( String.valueOf( ((JPasswordField) currentKey.lComponent).
                                        getPassword() ) );
                                method.invoke( cast, Property );
                            }
                            else
                            {
                                Integer Property = Integer.valueOf( ((JTextField) currentKey.lComponent).
                                        getText() );
                                method.invoke( cast, Property );
                            }
                        }
                        else if ( parameterTypes[0].getName().equals( "boolean" ) || parameterTypes[0].
                                getName().equals( "java.lang.Boolean" ) )
                        {
                            Boolean Property = Boolean.valueOf( ((JCheckBox) currentKey.lComponent).
                                    isSelected() );
                            method.invoke( cast, Property );
                        }
                    }
                }
            }
        }
        catch ( Exception ex )
        {
        }
    }

    /**
     * Sets the window Position
     * @param aThis The Widow container
     */
    private void setWindowParameters( Container aThis )
    {
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int x = (screenSize.width - aThis.getWidth()) / 2;
        int y = (screenSize.height - aThis.getHeight()) / 2;
        aThis.setBounds( x, y, aThis.getWidth(), aThis.getHeight() );
    }

    /**
     * Reads from properties to Bean
     * @return
     */
    private boolean readProperties()
    {
        String pClassName = this.getClass().getName();
        try
        {
            Class<?> forName = Class.forName( pClassName );
            Object cast = forName.cast( this );
            Method[] methods = forName.getMethods();
            for ( int i = 0; i < methods.length; i++ )
            {
                Method method = methods[i];
                if ( method.getDeclaringClass().getName().equals( pClassName )
                        && method.getName().startsWith( "set" ) )
                {
                    Field field = null;
                    try
                    {
                        field = forName.getField( lPrefixProps + method.getName().
                                substring( 3 ) + lSufixProps );
                    }
                    catch ( NoSuchFieldException ex )
                    {
                        continue;
                    }
                    if ( field == null )
                    {
                        continue;
                    }
                    KeyValue CurrentField = (KeyValue) field.get( cast );
                    Class<?>[] parameterTypes = method.getParameterTypes();
                    if ( parameterTypes[0].getName().equals( "java.lang.String" ) )
                    {
                        String stringProperty = getStringProperty(
                                CurrentField.key, CurrentField.isEncrypted );
                        method.invoke( cast, stringProperty );
                    }
                    else if ( parameterTypes[0].getName().equals( "int" ) || parameterTypes[0].
                            getName().equals( "java.lang.Integer" ) )
                    {
                        Integer cast1 = getIntegerProperty( CurrentField.key,
                                                            CurrentField.isEncrypted );
                        method.invoke( cast, cast1 );
                    }
                    else if ( parameterTypes[0].getName().equals( "double" ) || parameterTypes[0].
                            getName().equals( "java.lang.Double" ) )
                    {
                        Double cast1 = getDoubleProperty( CurrentField.key,
                                                          CurrentField.isEncrypted );
                        method.invoke( cast, cast1 );
                    }
                    else if ( parameterTypes[0].getName().equals( "float" ) || parameterTypes[0].
                            getName().equals( "java.lang.Float" ) )
                    {
                        Float cast1 = getFloatProperty( CurrentField.key,
                                                        CurrentField.isEncrypted );
                        method.invoke( cast, cast1 );
                    }
                    else if ( parameterTypes[0].getName().equals( "boolean" ) || parameterTypes[0].
                            getName().equals( "java.lang.Boolean" ) )
                    {
                        Boolean cast1 = getBooleanProperty( CurrentField.key,
                                                            CurrentField.isEncrypted );
                        method.invoke( cast, cast1 );
                    }
                }
            }
            return true;
        }
        catch ( Exception ex )
        {
        }
        return false;
    }

    /**
     * Creates a Empty XML Properties File
     */
    private void createNewXMLFile()
    {
        try
        {
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.
                    newInstance();
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
            Document doc = docBuilder.newDocument();
            Element rootElement = doc.createElement( "properties" );
            doc.appendChild( rootElement );
            TransformerFactory transformerFactory = TransformerFactory.
                    newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.setOutputProperty(
                    OutputKeys.DOCTYPE_SYSTEM,
                    "http://java.sun.com/dtd/properties.dtd" );
            DOMSource source = new DOMSource( doc );
            StreamResult result = new StreamResult( new File( lPropsFilePath ) );
            transformer.transform( source, result );
        }
        catch ( TransformerException ex )
        {
        }
        catch ( ParserConfigurationException ex )
        {
        }
    }

    /**
     * Returns the Data type of the field
     * @param lField name to find the Data type
     * @return Data type name as String
     */
    public String getDatatype( String lField )
    {
        String pClassName = this.getClass().getName();
        String lReturn = "";
        try
        {
            Class<?> forName = Class.forName( pClassName );
            String fieldName = forName.getField( lField ).getName();
            int lprefixIndex, lSufixIndex;

            if ( lPrefixProps.length() == 0 )
            {
                lprefixIndex = 0;
            }
            else
            {
                lprefixIndex = lPrefixProps.length() - 1;
            }
            if ( lSufixProps.length() == 0 )
            {
                lSufixIndex = 0;
            }
            else
            {
                lSufixIndex = lSufixProps.length();
            }

            String lmethodName = "get" + fieldName.substring( lprefixIndex,
                                                              fieldName.length() - lSufixIndex );
            Method method = forName.getMethod( lmethodName );
            lReturn = method.getReturnType().getName();
        }
        catch ( Exception ex )
        {
        }
        return lReturn;
    }
}
